package qx.hyj.petrescue.controller;


import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.ServletContext;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import qx.hyj.petrescue.VO.JsonResult;
import qx.hyj.petrescue.VO.Result;
import qx.hyj.petrescue.constens.ErrorCode;
import qx.hyj.petrescue.dto.LoginUser;
import qx.hyj.petrescue.entity.Family;
import qx.hyj.petrescue.entity.Friend;
import qx.hyj.petrescue.entity.Users;
import qx.hyj.petrescue.entity.Volunteer;
import qx.hyj.petrescue.exception.DescribeException;
import qx.hyj.petrescue.mapper.FriendMapper;
import qx.hyj.petrescue.mapper.Usermapper;
import qx.hyj.petrescue.service.UserService;

import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/Petrescue/users")
@Tag(name = "用户模块", description = "用户模块")
public class UserController {
    @Autowired
    private UserService userService;
    @Autowired
    private Usermapper usermapper;

    @Resource
    private FriendMapper friendMapper;

    @PostMapping("/login")
    @Operation(summary = "用户登录")
    public JsonResult<?> login(@RequestBody LoginUser user, HttpServletResponse response) {
        JSONObject loginResponse = new JSONObject();
        // 调用userService的login方法，获取token
        String t = Optional.ofNullable(userService.login(user)).orElse("");
        Users user1 = usermapper.login(user.getAccount());
        Cookie cookie = new Cookie("token", t);
        // 设置Cookie的路径为根路径
        cookie.setPath("/");
        // 设置Cookie的过期时间（单位为秒）
        cookie.setMaxAge(3600);
        loginResponse.put("user", user1);
        loginResponse.put("token", t);
        response.addCookie(cookie);
        return new JsonResult<>(loginResponse);
    }

    @PostMapping("/addUser")
    @Operation(summary = "用户注册")
    public JsonResult<Users> addUser(@RequestBody Users user) {
        Users user1 = userService.addUser(user);
        if (user1 != null) {
            return new JsonResult<>(user1);
        } else {
            return new JsonResult<>(null, ErrorCode.USER_ADD_FAIL);
        }
    }

    @PostMapping("/updateuser")
    @Operation(summary = "用户修改")
    public JsonResult<Users> updateUser(@RequestBody Users user, HttpServletRequest request) {
        Integer userId = (Integer) request.getAttribute("id");
        Users user1 = new Users();
        user1.setId(userId);
        Integer ADDOK = userService.updateUser(user, user1);
        if (ADDOK == 1) {
            return new JsonResult<>(user);
        } else {
            return new JsonResult<>(null, ErrorCode.USER_UPDATE_FAIL);
        }
    }

    @PostMapping("/updateAvatar")
    @Operation(summary = "用户头像修改")
    public JsonResult<Users> updateAvatar(@RequestParam("picture") MultipartFile picture, HttpServletRequest request) {
        // 1. 检查文件是否为空
        if (picture == null || picture.isEmpty()) {
            return new JsonResult<>(null, ErrorCode.FILE_EMPTY);
        }
        try {
            Integer userId = (Integer) request.getAttribute("id");
            String originalFilename = picture.getOriginalFilename();

            // 2. 验证文件扩展名
            String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
            if (!isValidExtension(extension)) {
                return new JsonResult<>(null, ErrorCode.INVALID_FILE_TYPE);
            }

            // 3. 生成安全文件名
            String fileName = generateSafeFilename(extension);

            // 获取项目根目录
            String projectRoot = System.getProperty("user.dir");

            String xdUrl = "http://localhost:8080/images/head/" +fileName;
            // 构建相对于项目根目录的图片路径
            String relativePath = projectRoot + File.separator + "images" + File.separator + "head";
            Path uploadPath = Paths.get(relativePath);

            // 创建目录（如果不存在）
            if (!Files.exists(uploadPath)) {
                Files.createDirectories(uploadPath);
            }

            // 7. 保存文件（含路径安全检查）
            Path filePath = uploadPath.resolve(fileName).normalize();
            if (!filePath.startsWith(uploadPath)) {
                return new JsonResult<>(null, ErrorCode.INVALID_FILE_PATH);
            }

            // 保存文件
            picture.transferTo(filePath);
            Users user = new Users();
            Users u = new Users();
            u.setId(userId);
            user.setAvatar(xdUrl);
            usermapper.updateUser(user, u);
            return new JsonResult<>(user);
        } catch (IOException e) {
            e.printStackTrace();
            return new JsonResult<>(null, ErrorCode.USER_TX_FAIL);
        }
    }

    private String generateSafeFilename(String extension) {
        return UUID.randomUUID().toString() + LocalDateTime.now().format(DateTimeFormatter.ofPattern("_yyyyMMdd_HHmmss")) + extension;
    }

    // 文件类型验证
    private boolean isValidExtension(String ext) {
        Set<String> allowed = Set.of(".jpg", ".jpeg", ".png", ".gif", ".webp");
        return allowed.contains(ext.toLowerCase());
    }

    @PostMapping("/addFamily")
    @Operation(summary = "加入我们")
    public JsonResult<JSONObject> addFamily(Family family, HttpServletRequest request) {
        JSONObject loginResponse = new JSONObject();
        Integer addFamily = usermapper.searchFamilyByPhone(family.getPhone());
        if (addFamily == null) {
            Integer userId = (Integer) request.getAttribute("id");
            Users userCondition = new Users();
            userCondition.setId(userId);
            family.setUserid(userId);
            usermapper.addFamily(family);
            Users user = new Users();
            user.setJsfamily(1);
            usermapper.updateUser(user, userCondition);
            loginResponse.put("Jsfamily", 1);
            return new JsonResult<>(loginResponse);
        } else {
            return new JsonResult<>(null, ErrorCode.FAMILY_ADD_FAIL);
        }
    }

    @PostMapping("/addVolunteer")
    @Operation(summary = "成为志愿者")
    public JsonResult<JSONObject> addVolunteer(Volunteer volunteer, HttpServletRequest request) {
        JSONObject loginResponse = new JSONObject();
        Integer addVolunteer = usermapper.searchVolunteerByPhone(volunteer.getPhone());
        if (addVolunteer == null) {
            Integer userId = (Integer) request.getAttribute("id");
            Users userCondition = new Users();
            userCondition.setId(userId);
            volunteer.setUserid(userId);
            usermapper.addVolunteer(volunteer);
            Users user = new Users();
            user.setZyz(1);
            usermapper.updateUser(user, userCondition);
            loginResponse.put("Zyz", 1);
            return new JsonResult<>(loginResponse);
        } else {
            return new JsonResult<>(null, ErrorCode.VOLUNTEER_ADD_FAIL);
        }
    }

    @GetMapping("/addFriend")
    @Operation(summary = "添加朋友")
    public Result<?> addFriend(@RequestParam Integer friendId, HttpServletRequest request) {
        Integer userId = (Integer) request.getAttribute("id");
        List<Friend> friends = friendMapper.selectList(Wrappers.<Friend>lambdaQuery()
                .eq(Friend::getUserId, userId)
                .eq(Friend::getFriendId, friendId)
                .or()
                .eq(Friend::getUserId, friendId)
                .eq(Friend::getFriendId, userId));
        if(friends.size()==1){
            friends.get(0).setIsOK(1);
            friendMapper.updateById(friends.get(0));
        }else if(friends.size()==0){
            Friend friend = new Friend().builder()
                    .userId(userId)
                    .friendId(friendId)
                    .isOK(0)
                    .createTime(LocalDateTime.now())
                    .build();
            friendMapper.insert(friend);
            return Result.success(friend);
        }else {
            throw new DescribeException(500, "已经成为朋友");
        }
        return null;
    }

    @GetMapping("/deleteFriend")
    @Operation(summary = "删除朋友")
    public Result<?> deleteFriend(@RequestParam Integer friendId, HttpServletRequest request) {
        Integer userId = (Integer) request.getAttribute("id");
        friendMapper.delete(Wrappers.<Friend>lambdaQuery()
                .eq(Friend::getUserId, userId)
                .eq(Friend::getFriendId, friendId));
        return Result.success();
    }

    @GetMapping("/getNewfriends")
    @Operation(summary = "获取新朋友")
    public Result<?> getNewfriends(HttpServletRequest request) {
        Integer userId = (Integer) request.getAttribute("id");
       return Result.success(friendMapper.selectNewFriendByUserId(userId)) ;
    }



    @GetMapping("/getfriends")
    @Operation(summary = "获取朋友")
    public Result<?> getfriends(HttpServletRequest request) {
        Integer userId = (Integer) request.getAttribute("id");
        List<Friend> friends = friendMapper.selectFriendByUserId(userId);
        if(CollectionUtils.isNotEmpty(friends)){
            Set<Integer> friendIds = new HashSet<>();
            Set<Integer> fID = friends.stream().map(Friend::getFriendId).collect(Collectors.toSet());
            Set<Integer> uID = friends.stream().map(Friend::getUserId).collect(Collectors.toSet());
            friendIds.addAll(fID);
            friendIds.addAll(uID);
            friendIds.remove(userId);
            return Result.success(usermapper.selectBatchIds(friendIds));
        }
        return Result.success() ;
    }

    @GetMapping("/selectUser")
    @Operation(summary = "获取用户信息")
    public Result<?> selectUser(@RequestParam String search) {
      return Result.success(usermapper.selectList(Wrappers.<Users>lambdaQuery()
              .like(Users::getNickname, search).or().eq(Users::getAccount, search)));
    }

}
